import { createRouter, createWebHashHistory } from 'vue-router'
import type { NavigationFailure, RouteLocationRaw, RouteRecordRaw } from 'vue-router'
import useBasicStore from '@/store/basic'
import md5 from 'blueimp-md5'

const routes: Array<RouteRecordRaw> = [
    {
        path: '/',
        redirect: '/login'
    },
    {
        path: '/login',
        name: 'login',
        component: () => import('@/views/login/Index.vue'),
        meta: {
            title: '用户登录',
            auth: false
        }
    },
    {
        path: '/home',
        name: 'home',
        redirect: '/front',
        meta: {
            auth: true
        }
    },
    {
        path: '/front',
        name: 'front',
        component: () => import('@/views/front/intro/Index.vue'),
        meta: {
            title: '首页',
            auth: true
        }
    },
    {
        path: '/largeScreen',
        name: 'largeScreen',
        component: () => import('@/views/front/largeScreen/Index.vue'),
        meta: {
            title: '大屏',
            auth: true
        }
    }
]

const dynamicRouters: Array<RouteRecordRaw> = [
    {
        path: '/back',
        name: 'back',
        component: () => import('components/back/common/Index-h.vue'),
        meta: {
            title: '管理后台',
            auth: true
        },
        children: [
            {
                path: '/monitoringCenter',
                name: 'monitoringCenter',
                component: () => import('@/views/back/monitoringCenter/Index.vue'),
                meta: {
                    title: '监控中心',
                    auth: true
                }
            },
            {
                path: '/realTimeMonitoring',
                name: 'realTimeMonitoring',
                component: () => undefined,
                meta: {
                    title: '实时监控',
                    auth: true
                }
            },
            {
                path: '/mainCompanyManage',
                name: 'mainCompanyManage',
                component: () => import('@/views/back/mainCompanyManage/Index.vue'),
                meta: {
                    title: '重点单位管理',
                    auth: true
                },
                children: [
                    {
                        path: '/mainCompanyManage/companyInfoManage',
                        name: 'companyInfoManage',
                        component: () => import('@/views/back/mainCompanyManage/companyInfoManage/Index.vue'),
                        meta: {
                            title: '单位信息管理',
                            auth: true
                        },
                    },
                    {
                        path: '/mainCompanyManage/companyUserManage',
                        name: 'companyUserManage',
                        component: () => import('@/views/back/mainCompanyManage/companyUserManage/Index.vue'),
                        meta: {
                            title: '单位人员管理',
                            auth: true
                        },
                    }
                ]
            },
            {
                path: '/dataAnalysis',
                name: 'dataAnalysis',
                component: () => import('@/views/back/dataAnalysis/Index.vue'),
                meta: {
                    title: '数据分析',
                    auth: true
                },
                children: [
                    {
                        path: '/dataAnalysis/deviceData',
                        name: 'deviceData',
                        component: () => import('@/views/back/dataAnalysis/DeviceData.vue'),
                        meta: {
                            title: '设备数据',
                            auth: true
                        }
                    },
                    {
                        path: 'dataStatistics',
                        name: 'dataStatistics',
                        component: () => undefined,
                        meta: {
                            title: '数据统计',
                            auth: true
                        }
                    }
                ]
            },
            {
                path: '/systemSetting',
                name: 'systemSetting',
                component: () => import('@/views/back/systemSetting/Index.vue'),
                meta: {
                    title: '系统配置',
                    auth: true
                },
                children: [
                    {
                        path: '/systemSetting/systemManage',
                        name: 'systemManage',
                        component: () => import('@/views/back/systemSetting/systemManage/Index.vue'),
                        meta: {
                            title: '系统管理',
                            auth: true
                        },
                        children: [
                            {
                                path: '/systemSetting/systemMange/userManage',
                                name: 'userManage',
                                component: () => import('@/views/back/systemSetting/systemManage/UserManage.vue'),
                                meta: {
                                    title: '用户管理',
                                    auth: true
                                }
                            },
                            {
                                path: '/systemSetting/systemMange/menuManage',
                                name: 'menuManage',
                                component: () => import('@/views/back/systemSetting/systemManage/MenuManage.vue'),
                                meta: {
                                    title: '菜单管理',
                                    auth: true
                                }
                            },
                            {
                                path: '/systemSetting/systemMange/roleManage',
                                name: 'roleManage',
                                component: () => import('@/views/back/systemSetting/systemManage/RoleManage.vue'),
                                meta: {
                                    title: '角色管理',
                                    auth: true
                                }
                            }
                        ]
                    },
                    {
                        path: '/systemSetting/deviceManage',
                        name: 'deviceManage',
                        component: () => import('@/views/back/systemSetting/deviceManage/Index.vue'),
                        meta: {
                            title: '设备管理',
                            auth: true
                        },
                        children: [
                            {
                                path: '/systemSetting/deviceManage/registerDevice',
                                name: 'registerDevice',
                                component: () => import('@/views/back/systemSetting/deviceManage/DeviceRegister.vue'),
                                meta: {
                                    title: '设备注册',
                                    auth: true
                                }
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

/**
 * 加密后的路由映射
 */
const md5RouterMap: Map<string, string> = new Map<string, string>()

/**
 * 是否对路由进行加密
 */
const isEncryptRouter: boolean = false

/**
 * 过滤权限路由
 * @param f 路由
 * @param p 权限
 */
const filterDynamicRouters = (f?: RouteRecordRaw[], p?: string[]): RouteRecordRaw[] => {
    if (!f || !p || !p.length) return []
    return f.filter(t => {
        let m = p.find(it => it === t.name)
        if (m) {
            if (t.children) {
                t.children = filterDynamicRouters(t.children, p)
            } else {
                Object.assign(t, { children: [] })
            }
        }
        return !!m
    })
}

const encryptRouters = (origin: RouteRecordRaw[]): RouteRecordRaw[] => {
    origin.forEach(r => {
        if (r.path !== '/') {
            if (!md5RouterMap.has(r.path)) {
                let er = encryptRouter(r.path)
                md5RouterMap.set(r.path, er)
                r.alias = er
            }
        }
        // if (r.redirect) r.redirect = encryptRouter(r.redirect.toString())
        if (r.children && r.children.length) encryptRouters(r.children)
    })
    return origin
}

const encryptRouter = (path: string): string => {
    /*
    let sp = path.split('/')
    for (let i = 0; i < sp.length; i++) {
        sp[i] = md5(sp[i])
    }
    return '/' + sp.join('')
    */
    return '/' + md5(encodeURIComponent(path))
}

/**
 * 定义一个代理函数创建router实例
 * @param permissions
 */
const defineProxyRouter = (permissions?: string[]) => {
    permissions = permissions ?? []
    // 刷新时，动态路由会丢失，pinia实例未初始化，但在localStorage | sessionStorage 中能访问到数据
    // 暂时的解决方案
    // const basicStore = useBasicStore()
    const basicStore = sessionStorage.getItem('basic')
    if (basicStore) {
        let uStore = JSON.parse(basicStore)
        permissions = uStore.permissions
    }
    const authRoutes = [...routes, ...filterDynamicRouters(dynamicRouters, permissions)]
    return createRouter({
        history: createWebHashHistory(),
        routes: isEncryptRouter ?  encryptRouters(authRoutes) : authRoutes,
        scrollBehavior: (from, to, savePosition) => {
            if (savePosition) {
                return savePosition
            } else {
                return { top: 0, left: 0 }
            }
        }
    })
}

/**
 * vue3如何重写push方法
 * 看源码了解返回的router结构进行解构
 * 或者重写resolve
 */
const { push, ...o } = defineProxyRouter()

const router = {
    push: (to: RouteLocationRaw): Promise<NavigationFailure | void | undefined> => {
        if (isEncryptRouter) {
            if (typeof to === 'string') {
                // @ts-ignore
                to = md5RouterMap.has(to) ? md5RouterMap.get(to) : to
            } else {
                // @ts-ignore
                to.path = md5RouterMap.has(to.path) ? md5RouterMap.get(to.path) : to.path
            }
        }
        try {
            return push(to)
        } catch (e) {
            return Promise.resolve(push(to))
        }
    },
    ...o
}

router.beforeEach((to, from, next) => {
    const uStore = useBasicStore()
    if (from.path === to.path) return false
    if (to.meta && to.meta.title) {
        // @ts-ignore
        window.document.title = to.meta.title
    }
    const p = to.path
    const nr: string | undefined = md5RouterMap.get(p)
    const ec = isEncryptRouter
    const ud = uStore.userDetail
    if (!to || !to.matched.length) {
        if (ec) {
            next({
                path: nr ?? encryptRouter('/login')
            })
        } else {
            next({
                path: '/login'
            })
        }
        return false
    }
    if (!to.meta || !to.meta.auth) {
        if (ec) {
            if (nr) {
                next({
                    path: nr
                })
                return false
            }
        }
        next()
    } else {
        if (ud) {
            if (ec) {
                if (nr) {
                    next({
                        path: nr
                    })
                    return false
                }
            }
            next()
        } else {
            next({
                path: ec ? encryptRouter('/login') : '/login'
            })
        }
    }
})

router.afterEach((to, from, next) => {
    // TODO 记录面包屑
    const uStore = useBasicStore()
    const { name, path, meta: { title } } = to
    uStore.updateCurrentRouters({ name, path, title })
    // window.scroll(0, 0)
})

export { dynamicRouters, isEncryptRouter, filterDynamicRouters, encryptRouters }

export default router
